package com.asa.a;

/**
 * 对象的加载过程
 * @author Administrator
 *
 */
public class L {
	
	
	
	/**
	 * 
	 * 1.判断对象对应的类是否加载、链接、初始化
	 *		 虚拟机遇到一-条new指令，首先去检查这个指令的参数能否在Metaspace的常量池中定位到-个类
			的符号引用，并且检查这个符号引用代表的类是否已经被加载、解析和初始化。 (即判断类元信息
			是否存在)。如果没有，那么在双亲委派模式下，使用当前类加载器以ClassLoader+包名+类名为
			Key进行查找对应的.class文件。如果没有找到文件，则抛出ClassNotFoundException异常，
			如果找到，则进行类加载工并生成对应的Class类对象
	 * 
	 * 
	 * 
	 * 2.为对象分配内存
	 * 		首先计算对象占用空间大小，接着在堆中划分一块内 存给新对象。
			如果实例成员变量是引用变量，仅分配引用变量空间即可，即4个字节大小。

			①如果内存规整-----指针碰撞
				如果内存是规整的，那么虚拟机将采用的是指针碰撞法( Bump The Pointer )来为对象分配内存。
				意思是所有用过的内存在一边，空闲的内存在另外一边，中间放着一个指针作为分界点的指示器，
				分配内存就仅仅是把指针向空闲那边挪动- -段与对象大小相等的距离罢了。如果垃圾收集 器选择
				的是Serial、ParNew这种基于压缩算法的，虚拟机采用这种分配方式。一般使用带有
				compact (整理)过程的收集器时，使用指针碰撞。

			
			
			②如果内存不规整-------------空闲列表分配
				如果内存不是规整的，已使用的内存和未使用的两存相互交错，那么虚拟机将采用的是空闲列表法来为对象分配内存。
				意思是虚拟机维护了一个列表，记录上哪些内存块是可用的，再分配的时候从列表中找到一块足够
				大的空间划分给对象实例，并更新列表上的内容。这种分配方式成为空闲列表( Free List ) "。
				
			选择哪种分配方式由Java堆是否规整决定,而Java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

				



	 * 	
	 *3.处理并发安全问题
			采用CAS失败重试、区域加锁保证更新的原子性
			每个线程预先分配一块TLAB 一通过 .XX:+/-UseTLAB参数来设定

	 * 
	 * 
	 * 4.初始化分配到的空间 一所有属性设置默认值 ,保证对象实例字段在不赋值时可以直接使用
			给对象的属性赋值的操作:
			③属性的默认初始化-②显式初始化/③代码块中初始化|④构造器中初始化
			这一步就是实现了①

	 * 
	 * 5.设置对象的对象头
			将对象的所属类(即类的元数据信息)、对象的HashCode和对象的GC信息、 锁信息等数据存储
			在对象的对象头中。这个过程的具体设置方式取决于JVM实现。
			基础的对象头是16字节，markword8，实例数据4，补齐4
	 * 
	 * 
	 * 
	 * 6.执行init方法进行初始化
			在Java程序的视角看来，初始化才正式开始。初始化成员变量，执行实例化代码块，调用类的构
			造方法，并把堆内对象的首地址赋值给引用变量。
			因此一般来说(由字节码中是否跟随有invokespecial指令所决定) , new指令之后会接着就是执
			行方法，把对象按照程序员的意愿进行初始化,这样一一个真正可用的对象才算完全创建出来。
			
			②显式初始化/③代码块中初始化|④构造器中初始化
			
	 * 
	 * 
	 * 
	 * 
	 * 
	 * JVM是如何通过栈帧中的对象引用访问到其内部的对象实例的呢?对象访问的定位
	 * 		句柄访问和直接指针
	 * 		
	 * 		句柄访问						有图
	 * 			eference中存储稳定句柄地址，对象被移动(垃圾收集时移动对象很普遍)时只会改变句柄中实
				列数据指针即可，reference本身不需要被修改。
				但它存在有三次寻址，调用链比较长

	 * 
	 * 		直接指针（Hotspot采用的这种方式）		有图
	 * 			
	 * 
	 * 
	 * 
	 */
	
	
	
	
	
	
	
	
	
	

}
